using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using NetTaste;
using SN.WebApi.Commons;
using SN.WebApi.Entities;
using SN.WebApi.Redis;
using SN.WebApi.Services;
using SqlSugar;
using StackExchange.Redis;

namespace SN.WebApi.Controllers;

[Route("api/[controller]/[action]")]
[ApiController]
public class UserController : ControllerBase
{
    private readonly ILogger<UserController> _logger;
    private readonly ISqlSugarClient _sqlSugarClient;
    private readonly IUserService _userService;

    private readonly IDatabase _db;
     private const string lockValue = "333333333333333";
    

    public UserController(ILogger<UserController> logger, ISqlSugarClient sqlSugarClient, IUserService userService)
    {
        _logger = logger;
        _sqlSugarClient = sqlSugarClient;
        _userService = userService;
        _db = RedisHelper.RedisConn.GetDatabase();
    }

    [HttpGet]
    public string TestAOP(string name)
    {

        //_sqlSugarClient.DbFirst.CreateClassFile("/Users/mac/Desktop/web_vue/webapi/SN.WebApi/Entities","SN.WebApi.Entities");
        return _userService.Login(name);
    }

    [HttpGet]
    public long GetNextId()
    {
        return RedisIdWorker.NextId("myprefix");
    }

    [HttpGet]
    public string Get()
    {
        var users = _sqlSugarClient.Queryable<User>().ToList();
        _logger.LogInformation("he  lll oo");
        return "diyige ";
    }

    [HttpPost]
    public string CreateSeckillVoucher(VoucherCreateDto dto)
    {
        var seckillEntity = dto.Adapt<tb_seckill_voucher>();
        //var voucherEntity = dto.vocherCreateDto.Adapt<tb_voucher>();
        _sqlSugarClient.Insertable(seckillEntity).ExecuteCommand();
        // _sqlSugarClient.Insertable(voucherEntity).ExecuteCommand();
        return "OK";
    }

    long GenerateUniqueId()
    {
        Guid guid = Guid.NewGuid();
        byte[] bytes = guid.ToByteArray();
        return BitConverter.ToInt64(bytes, 0);
    }


    [HttpPost]
    public string SeckVoucher(int id)
    {
        var tbseckilloucher = _sqlSugarClient.Queryable<tb_seckill_voucher>().First(x => id == id);
        // 1 秒杀是否开始
        if (DateTime.Now < tbseckilloucher.begin_time)
        {
            return "秒杀未开始";
        }
        // 2 秒杀是否结束
        if (DateTime.Now > tbseckilloucher.end_time)
        {
            return "秒杀已经结束";
        }
        // 3 库存是否充足
        if (tbseckilloucher.stock <= 0)
        {
            return "秒杀券不足";
        }
        var simpleRedis = new SimpleRedis("1", _db);
        if (!simpleRedis.Lock("1"))
        {
            return "单人只能抢购一次";
        }
        try
        {
            return CreateVoucherOrder(id, tbseckilloucher);
        }
        finally
        {
           simpleRedis.UnLock("1");
        }
    }
    

    private static readonly Object lockObj = new object();
    private string CreateVoucherOrder(int id, tb_seckill_voucher tbseckilloucher)
    {
        // 4.0 判断当前用户是否下过单
        var count = _sqlSugarClient.Ado.GetInt("select count(1) from tb_voucher_order where voucher_id=@voucher_id and user_id=@user_id", new List<SugarParameter>(){
                        new SugarParameter("@voucher_id",id),
                        new SugarParameter("@user_id",1)
            });
        if (count > 0)
        {
            return "当前用户已经下过单";
        }

        // 4 创建订单
        var tbvoucherorder = new tb_voucher_order();
        tbvoucherorder.id = RedisIdWorker.NextId("myprefix");//GenerateUniqueId();//snowflake.NextId();
        tbvoucherorder.user_id = (ulong)id;
        tbvoucherorder.voucher_id = 1;
        tbvoucherorder.pay_type = 1;
        tbvoucherorder.status = 1;
        tbvoucherorder.create_time = DateTime.Now;
        tbvoucherorder.update_time = DateTime.Now;
        // 5 库存减一
        var rt = _sqlSugarClient.Ado.ExecuteCommand("update tb_seckill_voucher set stock = stock-1 where stock>0 and voucher_id = " + tbseckilloucher.voucher_id);
        if (rt > 0)
        {
            _sqlSugarClient.Insertable(tbvoucherorder).ExecuteCommand();
        }
        return "OK";
    }
}

public class VoucherCreateDto
{
    public int stock { get; set; }
    public DateTime begin_time { get; set; }
    public DateTime end_time { get; set; }
    // public VocherCreateDto vocherCreateDto{get;set;}
}

public class VocherCreateDto
{
    public int shop_id { get; set; }
    public string title { get; set; }
    public string sub_title { get; set; }
    public string rules { get; set; }
    public int pay_value { get; set; }
    public int actual_value { get; set; }
    public string type { get; set; }
    public string status { get; set; } = "1";
}

public class User
{
    public string ID { get; set; }
    public string Name { get; set; }
    public string Phone { get; set; }
}
